/*
 * Copyright (c) 2024 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { Scene, SceneConfig } from "../../ArkAnalyzer/src";
import { GraphBuilder } from "../../Ark2Graph/graphBuilder";
import { Node } from "../../Ark2Graph/Nodes";
import { CfgEdge, DfgEdge, CgEdge } from "../../Ark2Graph/Edge";
import { Stmt } from "../../ArkAnalyzer/src/core/base/Stmt";
import { describe, expect, test } from "@jest/globals";
import path from "path";
import fs from "fs";
import { Connection } from "../../Ark2Graph/Client";

/*
    测试项：Ark2Graph的边构建功能
    标题：存放的CFG、CG、DFG列表属性一致
    级别：关键
    预置条件：正确的可执行的ts项目
    操作步骤：1.使用测试数据TestCallGraphConfig.json配置文件 
             2.对该数据的文件运行graphBuilder.build()
    预期结果：1.判断CFG、DFG、CG的列表是否存在类型不一致情况
    测试结果：符合预期结果
*/

describe("GraphBuilder Class", () => {
  let client: any;
  let graphBuilder: GraphBuilder;
  let CFGCount: any;
  let DFGCount: any;
  let CGCount: any;
  let NodeCount: any;
  const CFGquery = `
        .E().has('type', 'cfg').count()
    `;
  const DFGquery = `
        .E().has('type', 'dfg').count()
    `;
  const CGquery = `
        .E().has('type', 'cg').count()
    `;
  const Nodequery = `
        .V().count()
    `;

  beforeAll(async () => {
    client = await Connection.getClient();
    await client.submit('g.V().drop()');
    const configPath = path.resolve(
      __dirname,
      "../test_config/TestCallGraphConfig.json"
    );
    graphBuilder = new GraphBuilder(client, configPath);
    const configfile = JSON.parse(fs.readFileSync(configPath, "utf-8"));
    const filePath = configfile.fileTestConfigPath;
    let config: SceneConfig = new SceneConfig();
    config.buildFromJson(filePath);
    config.buildFromProjectDir(config.getTargetProjectDirectory());
    let scene = new Scene();
    scene.buildSceneFromProjectDir(config);
    graphBuilder.setScene(scene);
    await graphBuilder.buildCPG();
    let cypherBatch = "g";
    CFGCount = await client.submit(cypherBatch + CFGquery);
    DFGCount = await client.submit(cypherBatch + DFGquery);
    CGCount = await client.submit(cypherBatch + CGquery);
    NodeCount = await client.submit(cypherBatch + Nodequery);
  });

  afterAll(async () => {
    await client.submit('g.V().drop()');
    await client.close();
  });

  test("should initialize GraphBuilder correctly", () => {
    expect(graphBuilder).toBeDefined();
  });

  test("should build CFG edges correctly", () => {
    expect(CFGCount._items[0]).toBe(11);
  });

  test("should build DFG edges correctly", () => {
    expect(DFGCount._items[0]).toBe(6);
  });

  test("should build CG edges correctly", () => {
    expect(CGCount._items[0]).toBe(1);
  });

  test("should add nodes correctly", () => {
    expect(NodeCount._items[0]).toBe(13);
  });
});
